package com.kedacom.ctsp.authz.oauth2.provider;

import com.alibaba.fastjson.JSON;
import com.kedacom.ctsp.authz.AuthenticationService;
import com.kedacom.ctsp.authz.oauth2.core.OAuth2Exception;
import com.kedacom.ctsp.authz.oauth2.util.JWTHelper;
import com.kedacom.ctsp.authz.security.provider.AuthUserDetails;
import com.kedacom.ctsp.lang.StringUtil;
import com.kedacom.ctsp.web.controller.message.ResponseMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 在跳转登录之前拦截,如果已经sso单点登录了.则直接根据accessToken clientId clientSecret 获取用户信息
 *
 * @author fenghaiju
 * @create 2018/8/8
 **/
@Slf4j
public class RequestAuthenticationJWTFilter extends OncePerRequestFilter {
    private static String JWT_TOKEN = "jwt-token";

    @Autowired
    private AuthenticationService authenticationService;
    @Autowired
    private JWTHelper jwtHelper;

    /**
     * 通过参数中是否存在accessToken, 并且accessToken有效 被过滤
     *
     * @param request
     * @return
     */
    private boolean isInclude(HttpServletRequest request) {
        String jwtToken = request.getHeader(JWT_TOKEN);
        if (StringUtils.isNotBlank(jwtToken)) {
            return true;
        }
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String jwtTokenStr = request.getHeader(JWT_TOKEN);
        String username = null;
        String errorMsg = "";
        boolean flag = true;
        int code = 0;
        try {
            if (isInclude(request)) {
                try {
                    username = jwtHelper.getInfoFromToken(jwtTokenStr);
                } catch (Exception e) {
                    throw e;
                }
            }

            if (jwtTokenStr == null) {
                filterChain.doFilter(request, response);
                return;
            }
            //把登录信息设置到spring上下文中
            AuthUserDetails principal = new AuthUserDetails(authenticationService.loadUserByUsername(username));

            PreAuthenticatedAuthenticationToken auth =
                    new PreAuthenticatedAuthenticationToken(principal, username, principal.getAuthorities());

            SecurityContextHolder.getContext().setAuthentication(auth);
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            if (e instanceof OAuth2Exception) {
                code = StringUtil.toInt(((OAuth2Exception) e).getCode());
            }
            errorMsg = e.getMessage();
            flag = false;
        }
        //发生异常，直接返回错误提示
        if (!flag) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().println(JSON.toJSONString(ResponseMessage.error(code, errorMsg)));
            return;
        }
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        // 暂时先不用,client不用切换
        return false;
//        return isInclude(request);
    }
}
